<?php
declare (strict_types=1);

namespace app\controller;

use app\BaseController;
use app\common\Pay;
use app\common\UserService;
use app\job\Task;
use app\model\Config;
use app\model\Line;
use app\model\LineCoupon;
use app\model\LineOrders;
use app\model\LineOrdersAssess;
use app\model\LineSpot;
use app\model\LineTags;
use app\model\User;
use app\model\UserCoupon;
use app\tool\Random;
use DateTime;
use think\db\Query;
use think\facade\Db;
use think\facade\Log;
use think\facade\Queue;
use think\Request;

class LineController extends BaseController
{
	
	
	protected $order_timeout = 60 * 15;//订单超时时间
	
	
	function tags()
	{
		$rows = LineTags::select();
		$this->writeJson($rows);
	}
	
	function line()
	{
		$rows = Line::select();
		$this->writeJson($rows);
	}
	
	function list()
	{
		$line_id = $this->request->get('line_id/d');
		$keyword = $this->request->get('keyword');
		$score = $this->request->get('score');
		$tag_ids = $this->request->get('tag_ids');
		$sales = $this->request->get('sales');
		
		
		$rows = LineSpot::withCount('assess')
			->when(!empty($line_id), function (Query $query) use ($line_id) {
				$query->where('line_id', $line_id);
			})
			->when(!empty($keyword), function (Query $query) use ($keyword) {
				$query->whereLike('name', '%' . $keyword . '%');
			})
			->when(!empty($score), function (Query $query) use ($score) {
				$query->where('score', '>=',$score)->order(['score'=>'desc']);
			})
			->when(!empty($sales), function (Query $query) use ($sales) {
				$query->order('sales', $sales);
			})
			->when(!empty($tag_ids), function (Query $query) use ($tag_ids) {
				$arr = explode(',', $tag_ids);
				$whereRaw = '';
				foreach ($arr as $item) {
					$whereRaw .= "FIND_IN_SET('$item', `line_tag_ids`) OR ";
				}
				$whereRaw = rtrim($whereRaw, 'OR ');
				$query->whereRaw($whereRaw);
			})
			->filter(function ($data){
				if ($data->score > 4 ){
					$data->score_text = '很好';
				}elseif ($data->score > 3){
					$data->score_text = '良好';
				}elseif($data->score > 2){
					$data->score_text = '一般';
				}else{
					$data->score_text = '差';
				}
			})
			->order(['id' => 'desc'])
			->paginate()
			->items();
		$this->writeJson($rows);
	}
	
	/**
	 * 收藏
	 */
	function collect()
	{
		$spot_id = $this->request->post('spot_id/d');
		$ret = UserService::collect($spot_id, $this->user_id);
		$this->writeJson($ret);
	}
	
	function detail()
	{
		$spot_id = $this->request->get('spot_id/d');
		$row = LineSpot::with(['stop', 'user_collect'=>function (Query $query) {
			$query->where('user_id',$this->user_id);
		}])
			->withCount('assess')
			->withCount(['assess' => function (Query $query, &$alias) {
				$query->whereIn('score', [4, 5]);
				$alias = 'assess_good_count';
			}])
			->filter(function ($data) {
				$data->score = round($data->score ,1);
				if ($data->assess_count == 0) {
					$data->assess_msg = '暂无评价';
				} else {
					$assess_good_ratio = round($data->assess_good_count / $data->assess_count * 100, 2);
					if ($assess_good_ratio > 80) {
						$data->assess_msg = '好评·' . $assess_good_ratio . '%好评率';
					} elseif ($assess_good_ratio > 50) {
						$data->assess_msg = '中评·' . $assess_good_ratio . '%好评率';
					}else{
						$data->assess_msg = '差评·' . $assess_good_ratio . '%好评率';
					}
				}
			})
			->findOrFail($spot_id);
		$this->writeJson($row);
	}
	
	function assessList()
	{
		$spot_id = $this->request->get('spot_id/d');
		$status0 = LineOrdersAssess::where(['spot_id'=>$spot_id])->count();
		$status1 = LineOrdersAssess::where(['spot_id'=>$spot_id])->where('score','5')->count();
		$status2 = LineOrdersAssess::where(['spot_id'=>$spot_id])->where('score','4')->count();
		$status3 = LineOrdersAssess::where(['spot_id'=>$spot_id])->where('score','3')->count();
		$status4 = LineOrdersAssess::where(['spot_id'=>$spot_id])->where('score','2')->count();
		$status5 = LineOrdersAssess::where(['spot_id'=>$spot_id])->where('score','1')->count();
		$status1 = $status0==0?0:$status1/$status0*100;
		$status2 = $status0==0?0:$status2/$status0*100;
		$status3 = $status0==0?0:$status3/$status0*100;
		$status4 = $status0==0?0:$status4/$status0*100;
		$status5 = $status0==0?0:$status5/$status0*100;
		$rows = LineOrdersAssess::with(['user'])
			->where(['spot_id'=>$spot_id])
			->paginate()
			->items();
		$this->writeJson(['list'=>$rows,'status'=>['status1'=>$status1,'status2'=>$status2,'status3'=>$status3,'status4'=>$status4,'status5'=>$status5]]);
		
	}
	
	function confirmOrder()
	{
		$spot_id = $this->request->post('spot_id/d');
		$child_count = $this->request->post('child_count/d');
		$adult_count = $this->request->post('adult_count/d');
		$coupon_id = $this->request->post('coupon_id/d');
		Log::record($this->request->param());
	
		$spot = LineSpot::findOrFail($spot_id);
		if($spot->line_id==1){
			$total_amount = $spot->deposit * ($adult_count + $child_count); // 总金额 = 押金 * 出行人数
		}else{
			$total_amount = bcadd(bcmul((string)$spot->price, (string)$adult_count, 2), bcmul((string)$spot->child_price, (string)$child_count, 2), 2);//总金额=成人总价 + 儿童总价
		}
		$coupon_amount = '0'; //优惠券金额
		if (!empty($coupon_id)) {
			$coupon = UserCoupon::findOrFail($coupon_id);
			if ($coupon->expiretime <= time()) {
				$this->writeJson(0, '优惠券已过期');
			}
			if ($coupon->status != 1) {
				$this->writeJson(0, '优惠券已被使用');
			}
			$couponDetail = $coupon->coupon;
			if ($couponDetail['scene'] == 1) {
				if ($couponDetail['spot_id'] != $spot->id) {
					$this->writeJson(0, '此优惠券不属于本商品');
				}
			}
			if ($couponDetail['type'] == 1 && $couponDetail['with_amount'] > $total_amount) {
				$this->writeJson(0, '订单金额不满足满减金额');
			}
			$coupon_amount = $couponDetail['amount'];
			
		}
		
		$pay_amount = bcsub((string)$total_amount, $coupon_amount, 2);
		if ($pay_amount <= 0) {
			$pay_amount = 0.01;
		}
		$this->writeJson(['spot' => $spot, 'pay_amount' => $pay_amount, 'coupon_amount' => $coupon_amount, 'total_amount' => $total_amount]);
	}
	
	function couponList()
	{
		$spot_id = $this->request->get('spot_id/d');
		$usercouponids = UserCoupon::where(['user_id' => $this->user_id])->column('coupon_id');
		
		$coupon = LineCoupon::where(function (Query $query) use ($spot_id) {
			$query->whereOr('spot_id', $spot_id)->whereOr('scene', 2);
		})->whereNotIn('id', $usercouponids)->where('num', '>', 0)->select();
		$this->writeJson($coupon);
	}
	
	/**
	 * 领取优惠券
	 * @return void
	 */
	function receiveCoupon()
	{
		$coupon_id = $this->request->post('coupon_id/d'); //优惠券ID
		$coupon = LineCoupon::findOrFail($coupon_id);
		if ($coupon->num == 0) {
			$this->writeJson(0, '优惠券被领完了');
		}
		
		$user = User::findOrFail($this->user_id);
		if ($user->level == 1) {
			$this->writeJson(0, '请先开通会员');
		}

		$row = UserCoupon::where(['user_id' => $this->user_id, 'coupon_id' => $coupon_id])->find();
		if ($row) {
			$this->writeJson(0, '不能重复领取');
		}
		$coupon->num -= 1;
		$coupon->save();
		UserCoupon::create([
			'user_id' => $this->user_id,
			'coupon_id' => $coupon_id,
			'coupon' => $coupon,
			'expiretime' => strtotime('+' . $coupon->expire_day . 'day', time())
		]);
		$this->writeJson();
	}
	
	/**
	 * 检查优惠券
	 * @return void
	 */
	function checkCoupon()
	{
		$spot_id = $this->request->post('spot_id/d');
		$child_count = $this->request->post('child_count/d');
		$adult_count = $this->request->post('adult_count/d');
		$spot = LineSpot::findOrFail($spot_id);
		
		$total_amount = bcadd(bcmul((string)$spot->price, (string)$adult_count, 2), bcmul((string)$spot->child_price, (string)$child_count, 2), 2);//总金额=成人总价 + 儿童总价
		
		$coupon = UserCoupon::where(['user_id' => $this->user_id, 'status' => 1])->select();//全部优惠券
		$valid = [];//有效优惠券
		$invalid = [];//无效优惠券
		foreach ($coupon as $k) {
			$detail = $k->coupon;
			if ($k->expiretime <= time()) {
				$k->msg = '优惠券已过期';
				$invalid[] = $k;
				continue;
			}
			if ($detail['scene'] == 1) {
				//指定商品
				if ($detail['spot_id'] == $spot->id) {
					if ($detail['type'] == 1) {
						if ($detail['with_amount'] > $total_amount) {
							//不满足
							$k->msg = '订单金额不满足满减金额';
							$invalid[] = $k;
						} else {
							//满足
							$k->msg = '666';
							$valid[] = $k;
						}
					} else {
						$k->msg = '666';
						$valid[] = $k;
					}
				} else {
					$k->msg = '不支持此商品';
					$invalid[] = $k;
				}
			} else {
				if ($detail['type'] == 1) {
					if ($detail['with_amount'] > $total_amount) {
						//不满足
						$k->msg = '订单金额不满足满减金额';
						$invalid[] = $k;
					} else {
						//满足
						$k->msg = '666';
						$valid[] = $k;
					}
				} else {
					$k->msg = '666';
					$valid[] = $k;
				}
			}
		}
		$this->writeJson(['valid' => $valid, 'invalid' => $invalid]);
	}
	
	
	function createOrder()
	{
		$spot_id = $this->request->post('spot_id/d');
		$child_count = $this->request->post('child_count/d');
		$adult_count = $this->request->post('adult_count/d');
		$coupon_id = $this->request->post('coupon_id/d');
		$day = $this->request->post('day');
		$members = $this->request->post('members/a');
		if (empty($members)) {
			$this->writeJson(0, '请选择出行人');
		}
		$spot = LineSpot::findOrFail($spot_id);
		$user = User::findOrFail($this->user_id);
		$members_count = count($members);
		
		$date1 = new DateTime(date('Y-m-d'));
		$date2 = new DateTime($day);
		$interval = date_diff($date1, $date2);
		$days = $interval->format('%a');
		
		$delay_days = Config::getFieldByName('delay_day', 'value');
		if ($days < $delay_days) {
			$this->writeJson(0, '出行日期有误');
		}
		$member_count = $adult_count + $child_count;
		if ($member_count != $members_count) {
			$this->writeJson(0, '出行人数量不一致');
		}
		if ($spot->line_id == 1) {
			if ($user->level == 1) {
				$this->writeJson(0, '请先开通会员');
			}
			if (!empty($coupon_id)){
				$this->writeJson(0,'非会员无法使用优惠券');
			}
			if ($members_count < 2) {
				$this->writeJson(0, '会员路线最少出行2人');
			}
			$total_amount = $spot->deposit * ($adult_count + $child_count); // 总金额 = 押金 * 出行人数
		} else {
			$total_amount = bcadd(bcmul((string)$spot->price, (string)$adult_count, 2), bcmul((string)$spot->child_price, (string)$child_count, 2), 2);//总金额=成人总价 + 儿童总价
		}
		
		$coupon_amount = 0; //优惠券金额
		if (!empty($coupon_id)) {
			$coupon = UserCoupon::findOrFail($coupon_id);
			if ($coupon->expiretime <= time()) {
				$this->writeJson(0, '优惠券已过期');
			}
			if ($coupon->status != 1) {
				$this->writeJson(0, '优惠券已被使用');
			}
			$couponDetail = $coupon->coupon;
			if ($couponDetail['scene'] == 1) {
				if ($couponDetail['spot_id'] != $spot->id) {
					$this->writeJson(0, '此优惠券不属于本商品');
				}
			}
			if ($couponDetail['type'] == 1 && $couponDetail['with_amount'] > $total_amount) {
				$this->writeJson(0, '订单金额不满足满减金额');
			}
			$coupon_amount = $couponDetail['amount'];
			//使用优惠券
			$coupon->status = 2;
			$coupon->save();
		}
		
		$pay_amount = $total_amount - $coupon_amount;
		if ($pay_amount <= 0) {
			$pay_amount = 0.01;
		}
		$ordersn = Random::ordersn();
		
		// 启动事务
		Db::startTrans();
		try {
			$order = LineOrders::create([
				'spot_id' => $spot_id,
				'user_id' => $this->user_id,
				'coupon_id' => $coupon_id,
				'total_amount' => $total_amount,
				'pay_amount' => $pay_amount,
				'coupon_amount' => $coupon_amount,//优惠券金额
				'order_sn' => $ordersn,
				'day' => $day,
				'child_count'=>$child_count,
				'adult_count'=>$adult_count,
			]);
			$order->member()->saveAll($members);
			// 提交事务
			Db::commit();
		} catch (\Exception $e) {
			// 回滚事务
			Db::rollback();
			$this->writeJson(0, $e->getMessage());
		}
		
		$order->canceltime_s = $order->getData('createtime') + $this->order_timeout;
		$order->createtime_s = $order->getData('createtime');
		
		Queue::later($this->order_timeout, Task::class, ['order_id' => $order->id, 'action' => 'line_order_timeout'], 'task');
		$this->writeJson($order);
	}
	
	#订单支付
	function orderPay()
	{
		$order_id = $this->request->post('order_id/d');
		$pay_type = $this->request->post('pay_type/d');
		$row = LineOrders::where(['user_id' => $this->user_id, 'status' => 1])->findOrFail($order_id);
		$user = User::findOrFail($this->user_id);
		$ordersn = Random::ordersn();
		// 启动事务
		Db::startTrans();
		try {
			$row->order_sn = $ordersn;
			$row->save();
			$ret = Pay::pay($pay_type, $row->pay_amount, $ordersn, '购买商品', 'line', $user->openid);
			// 提交事务
			Db::commit();
		} catch (\Exception $e) {
			// 回滚事务
			Db::rollback();
			$this->writeJson(0, $e->getMessage());
		}
		$this->writeJson($ret);
	}
	
	function orderList()
	{
		$status = $this->request->get('status/d'); #0全部 1待支付 2待出行 3待点评 4取消
		
		$rows = LineOrders::where(['user_id' => $this->user_id])
			->with(['spot'])
			->when(!empty($status), function (Query $query) use ($status) {
				if ($status == 1) {
					$query->where('status', 1);
				}
				if ($status == 2) {
					$query->where('status', 2);
				}
				if ($status == 3) {
					$query->where('status', 3);
				}
				if ($status == 4) {
					$query->where('status', 5);
				}
			})
			->order('id', 'desc')
			->paginate()
			->items();
		$this->writeJson($rows);
	}
	
	function orderDetail()
	{
		$order_id = $this->request->get('order_id/d');
		$row = LineOrders::where(['user_id' => $this->user_id])
			->with(['spot', 'member'])
			->filter(function ($data) {
				if ($data->status == 1) {
					$data->canceltime_s = $data->getData('createtime') + $this->order_timeout;
					$data->createtime_s = $data->getData('createtime');
				}
			})
			->findOrFail($order_id);
		$this->writeJson($row);
	}
	
	function orderCancel()
	{
		$order_id = $this->request->post('order_id/d');
		$row = LineOrders::where(['user_id' => $this->user_id])->findOrFail($order_id);
		if (!in_array($row->status, [1, 2])) {
			$this->writeJson(0, '此订单无法取消');
		}
		if ($row->status == 2) {
			if ($row->spot->line_id == 1) {
				//待出行  并且是会员
				$this->writeJson(0, '会员路线无法取消');
			} else {
				if (time() - $row->getData('createtime') >= 86400) {
					//待出行  并且是普通路线
					$this->writeJson(0, '已经超出24小时，无法取消');
				}
			}
		}
		// 启动事务
		Db::startTrans();
		try {
			$row->status = 5;
			$row->canceltime = time();
			if ($row->status == 2) {
				$refund_order_sn = Random::ordersn();
				Pay::refund(1, $row->pay_amount, $row->order_sn, $refund_order_sn, '申请退款');
				$row->refund_order_sn = $refund_order_sn;
				$row->status = 7;
			}
			$row->save();
			// 提交事务
			Db::commit();
		} catch (\Exception $e) {
			// 回滚事务
			Db::rollback();
			$this->writeJson(0, $e->getMessage());
		}
		$this->writeJson();
	}
	
	
	function orderDelete()
	{
		$order_id = $this->request->post('order_id/d');
		$row = LineOrders::where(['user_id' => $this->user_id])->findOrFail($order_id);
		
		if ($row->status != 5) {
			$this->writeJson(0, '订单状态错误');
		}
		$row->delete();
		$this->writeJson();
	}
	
	#订单退押金
	function orderRefundDeposit()
	{
		$order_id = $this->request->post('order_id/d');
		$bill = $this->request->post('bill');
		$reason = $this->request->post('reason');
		$row = LineOrders::where(['user_id' => $this->user_id])->findOrFail($order_id);
		if (!in_array($row->status, [3, 4])) {
			$this->writeJson(0, '订单状态错误');
		}
		if ($row->spot->line_id != 1) {
			$this->writeJson(0, '此订单不是会员路线');
		}
		$row->status = 6;
		$row->reason = $reason;
		$row->bill = $bill;
		$row->save();
		$this->writeJson();
	}
	
	#订单评价
	function orderAssess()
	{
		$order_id = $this->request->post('order_id/d');
		$score = $this->request->post('score/d', 5);
		$images = $this->request->post('images', '');
		$content = $this->request->post('content', '');
		$title = $this->request->post('title', '');
		$day = $this->request->post('day');
		$type = $this->request->post('type');
		if (!$content) {
			$this->writeJson(0, '评论内容不能为空');
		}
		if (!$title) {
			$this->writeJson(0, '评论标题不能为空');
		}
		$order = LineOrders::findOrFail($order_id);
		
		if ($order->status != 3) {
			$this->writeJson(0, '订单状态错误');
		}
		
		LineOrdersAssess::create([
			'user_id' => $this->user_id,
			'spot_id' => $order->spot_id,
			'order_id' => $order->id,
			'score' => $score,
			'images' => $images,
			'content' => $content,
			'day' => $day,
			'type' => $type,
			'title' => $title,
		]);
		$count = LineOrdersAssess::where(['spot_id' => $order->spot_id])->count();
		$score = LineOrdersAssess::where(['spot_id' => $order->spot_id])->sum('score');
		$score = round($score / $count, 1);
		$order->spot->score = $score;
		$order->status = 4;
		$order->together(['spot'])->save();
		$this->writeJson();
	}
	
	
	
}
